package com.xbongbong.pro.statistic.service.impl;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.help.UserAndDepartmentHelp;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.domain.entity.DataWarningEntity;
import com.xbongbong.pro.statistic.pojo.DwExecutorPojo;
import com.xbongbong.pro.statistic.service.DwExecutorService;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;


/**
 * @ClassName DwExecutorServiceImpl
 * @Description 获取关联执行人
 * @Author mengna.Deng
 * @Date 2021/4/30 14:22
 * @Version 1.0
 */
@Service("DwExecutorService")
public class DwExecutorServiceImpl implements DwExecutorService {
    private static final Logger LOG = LoggerFactory.getLogger(DwExecutorServiceImpl.class);
    @Resource
    private UserModel userModel;
    @Resource
    private UserAndDepartmentHelp userAndDepartmentHelp;

    @Override
    public List<DwExecutorPojo> getExecutorList(String corpid, List<DataWarningEntity> dwList) {
        // 部门id/角色id列表（查全公司使用）
        Set<Long> deptIdList = new HashSet<>();
        Set<Integer> roleIdList = new HashSet<>();

        // 数据预警对应对应的员工ids/部门ids/角色ids
        Map<Long, Set<String>> userIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, Set<Long>> deptIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, Set<Integer>> roleIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        // 设置对应的数据（员工/部门/角色）
        getExecutorTypeData(dwList, deptIdList, roleIdList, userIdsMap, deptIdsMap, roleIdsMap);


        // 部门对应员工
        Map<Long, List<String>> userIdsForDept = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (deptIdList.size() > 0) {
            List<Map<String, Object>> userIdsForDepMapList = userModel.getUserIdsJoinDeptGroup(corpid, deptIdList);
            for (Map<String, Object> userIdsForDepMap : userIdsForDepMapList) {
                Long depId = (Long) userIdsForDepMap.get("depId");
                String userIdsStr = (String) userIdsForDepMap.get("userIds");
                List<String> userIds = StringUtil.toStringList(userIdsStr, StringConstant.COMMA);
                userIdsForDept.put(depId, userIds);
            }
        }

        // 角色对应的员工
        Map<Integer, List<String>> userIdsForRole = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (roleIdList.size() > 0) {
            Map<Integer, List<String>> roleUserMap = userAndDepartmentHelp.userIdsForRole(corpid);
            for (Integer roleId : roleIdList) {
                if (roleUserMap.containsKey(roleId)) {
                    userIdsForRole.put(roleId, roleUserMap.get(roleId));
                }
            }
        }

        List<DwExecutorPojo> executorList = new ArrayList<>();
        dwList.forEach(entity -> {
            // 执行人实体
            Set<String> execUserIds =  normalExecutorList(userIdsForDept,userIdsForRole, userIdsMap, deptIdsMap, roleIdsMap, entity.getId());
            List<UserEntity> execUserList = userModel.getByUserIdIn(corpid, execUserIds);
            executorList.add(new DwExecutorPojo(entity.getId(),new ArrayList<>(execUserIds),execUserList));
        });

        return executorList;

    }

    /**
     * 获取相关的执行人数据
     *
     * @param dwList             智能助手列表
     * @param deptIdList            所有部门列表
     * @param roleIdList            所有角色列表
     * @param userIdsMap            员工map{smartId:[userId1,userId2]}
     * @param deptIdsMap            部门map{smartId:[deptId1,deptId2]}
     * @param roleIdsMap            角色map{smartId:[roleId1,roleId2]}
     * @return
     * @throws
     * @Author mengna.Deng
     * @Date 2021/4/30 14:22
     * @version v1.0
     * @since v1.0
     */
    private void getExecutorTypeData(List<DataWarningEntity> dwList, Set<Long> deptIdList, Set<Integer> roleIdList,
                                      Map<Long, Set<String>> userIdsMap, Map<Long, Set<Long>> deptIdsMap,
                                     Map<Long, Set<Integer>> roleIdsMap) {

        dwList.forEach(item -> {
            List<OptionalRangeEntity> rangeList = item.getExecutor().toJavaList(OptionalRangeEntity.class);
            Set<Long> deptIds = new HashSet<>();
            Set<Integer> roleIds = new HashSet<>();
            Set<String> userIds = new HashSet<>();
            rangeList.forEach(rangeEntity -> {
                OptionalRangeEnum rangeEnum = OptionalRangeEnum.getByValue(rangeEntity.getProperty());
                if (rangeEnum != null) {
                    switch (rangeEnum) {
                        case DEPT:
                            Long deptId = Long.parseLong(rangeEntity.getId());
                            deptIdList.add(deptId);
                            deptIds.add(deptId);
                            break;
                        case USER:
                            userIds.add(rangeEntity.getId());
                            break;
                        case ROLE:
                            Integer roleId = Integer.parseInt(rangeEntity.getId());
                            roleIdList.add(roleId);
                            roleIds.add(roleId);
                            break;
                        default:
                            break;
                    }
                }
            });

            // 数据预警对应的部门ids
            deptIdsMap.put(item.getId(), deptIds);
            // 数据预警对应的员工ids
            userIdsMap.put(item.getId(), userIds);
            // 数据预警对应的角色ids
            roleIdsMap.put(item.getId(), roleIds);
        });
    }

    /**
     * 获取常用执行人员
     *
     * @param userIdsForDept 部门员工map{deptId:[userId1,userId2]}
     * @param userIdsForRole 角色员工map{roleId:[userId1,userId2]}
     * @param userIdsMap     执行员工map{smartId:[userId1,userId2]}
     * @param deptIdsMap     执行部门map{smartId:[deptId1,deptId2]}
     * @param roleIdsMap     执行角色map{smartId:[roleId1,roleId2]}
     * @return
     * @throws
     * @Author mengna.Deng
     * @Date 2021/4/30 14:22
     * @version v1.0
     * @since v1.0
     */
    private Set<String> normalExecutorList(Map<Long, List<String>> userIdsForDept, Map<Integer, List<String>> userIdsForRole,
                                           Map<Long, Set<String>> userIdsMap, Map<Long, Set<Long>> deptIdsMap, Map<Long, Set<Integer>> roleIdsMap, Long dataWarningId) {
        // 当前需要执行的人员
        Set<String> execUserIds = userIdsMap.get(dataWarningId);
        Set<Long> execDepIds = deptIdsMap.get(dataWarningId);
        Set<Integer> execRoleIds = roleIdsMap.get(dataWarningId);

        if (Objects.isNull(execUserIds)) {
            execUserIds = new HashSet<>();
        }

        // 添加部门执行人
        if (Objects.nonNull(execDepIds) && !execDepIds.isEmpty()) {
            for (Long depId : execDepIds) {
                if (userIdsForDept.containsKey(depId)) {
                    execUserIds.addAll(userIdsForDept.get(depId));
                }
            }
        }
        // 添加角色执行人
        if (Objects.nonNull(execRoleIds) && !execRoleIds.isEmpty()) {
            for (Integer roleId : execRoleIds) {
                if (userIdsForRole.containsKey(roleId)) {
                    execUserIds.addAll(userIdsForRole.get(roleId));
                }
            }
        }

        return execUserIds;
    }
}
